#!/usr/bin/env python
# -*- coding:utf-8 -*-

import time,hashlib,json
import models
from django.shortcuts import render,HttpResponse
from myCMDB import settings

from django.core.exceptions import ObjectDoesNotExist
def json_date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.strftime("%Y-%m-%d")


def json_datetime_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.strftime("%Y-%m-%d %H:%M:%S")


def generate_token(username,timestamp,token):
    #和客户端统一，包括组成字符串的格式和截取hash值的长度
    token_format = "%s\n%s\n%s" %(username,timestamp,token)
    obj = hashlib.md5()
    obj.update(token_format)
    return obj.hexdigest()[10:17]


def token_required(func):   #被装饰的函数是整个装饰器的参数，下面的*args是被装饰函数的参数传给装饰器
    def wrapper(*args,**kwargs):    #*args是一个列表，如果就一个参数就要取args[0]
        response = {"errors":[]}

        get_args = args[0].GET  #request.GET,因为权限验证的信息是以get方式提交的，所以获取get的值
        username = get_args.get("user")
        token_md5_from_client = get_args.get("token")
        timestamp = get_args.get("timestamp")
        if not username or not timestamp or not token_md5_from_client:
            #如果get请求字段里少了任何一项，都会返回一个错误的response
            response['errors'].append({"auth_failed":"This api requires token authentication!"})
            return HttpResponse(json.dumps(response))
        try:
            user_obj = models.UserProfile.objects.get(email=username)
            token_md5_from_server = generate_token(username,timestamp,user_obj.token)
            #token_id是存储在mysql表中,生成hash后的md5-token，和客户端传过来的进行对比
            if token_md5_from_client != token_md5_from_server:
                response['errors'].append({"auth_failed":"Invalid username or token_id"})
            else:
                if abs(time.time() - int(timestamp)) > settings.TOKEN_TIMEOUT:
                    # default timeout 120，在settings中自定义此字段
                    response['errors'].append({"auth_failed":"The token is expired!"})
                else:
                    pass #print "\033[31;1mPass authentication\033[0m"
                    '''token能对应上了，但还有一次访问失效的配置，把所有访问的MD5-token存在一个地方
                    如memcache或redis（防止存在本机重启后清空，因为时间差而通过黑客的验证）
                    为了防止这个表过大，可以根据时间戳5分钟就过期，超过5分钟的就不予验证'''

                print "\033[41;1m;%s ---client:%s\033[0m" %(time.time(),timestamp), time.time() - int(timestamp)
        except ObjectDoesNotExist,e:
            response['errors'].append({"auth_failed":"Invalid username or token_id"})
        if response['errors']:
            return HttpResponse(json.dumps(response))
        else:
            return  func(*args,**kwargs)
    return wrapper
